package com.m3958.firstgwt.server.servlet;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.persist.Transactional;
import com.m3958.firstgwt.server.model.Article;
import com.m3958.firstgwt.server.model.Section;
import com.m3958.firstgwt.server.model.User;
import com.m3958.firstgwt.server.service.AppUtilService;
import com.m3958.firstgwt.server.service.FilePathService;
import com.m3958.firstgwt.server.session.ErrorMessages;
import com.m3958.firstgwt.server.session.SessionUser;
import com.m3958.firstgwt.server.utils.JsonlibDateValueProssor;

@Singleton
public class AdminToolsServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Inject
	protected com.google.inject.Provider<EntityManager> emp;
	
	@Inject
	private Injector injector;
	
	@Inject
	private AppUtilService autils;
	
	@Inject @Named("tcmsds")
	private DataSource tcmsds;
	
	@Inject
	private FilePathService fps;
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		doPost(req, res);
		
	}
	
	//admintools?task=exportfolder&fromid=rsdt
	//admintools?task=exportfolder&toid=55
	//admintools?task=queryid&rid=rsdt
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res)
		throws ServletException, IOException {
		SessionUser su = injector.getInstance(SessionUser.class);
		if(!su.isLogined() || !su.isSuperman()){
			return;
		}
		User u = emp.get().find(User.class, su.getUserId());
		String task = req.getParameter("task");
		File wr = new File(getServletContext().getRealPath("/"));
		int count = 0;
		if("exportfolder".equals(task)){
			String id = req.getParameter("fromid");
			if(id == null)return;
			if(id.length() != 32){
				List<String> ids = readableToId(id);
				if(ids.size() == 1){
					id = ids.get(0);
				}else{
					autils.writeHtmlResponse(res, "对应多个ID");
					return;
				}
			}
			if(id.length() == 32){
				count = exportFolder(id,wr);
			}
		}else if("importfolder".equals(task)){
			int toid = Integer.parseInt(req.getParameter("toid"));
			count = importFolder(toid, wr,u);
		}else if("queryid".equals(task)){
			List<String> ids = readableToId(req.getParameter("rid"));
			String ss = "";
			for(String s : ids){
				ss += s + ",";
			}
			autils.writeHtmlResponse(res, ss);
			return;
		}
		autils.writeHtmlResponse(res, String.valueOf(count));
	}
	
	private List<String> readableToId(String readable){
		List<String> ids = new ArrayList<String>();
		Connection cn = null;
		try {
			    cn = tcmsds.getConnection();
			    String query = "select id from section_bases where myreadableId = '" + readable + "'";
	            Statement st = cn.createStatement();
	            ResultSet rs = st.executeQuery(query);
	            if(rs.next()){
	            	ids.add(rs.getString("id"));
	            }
		} catch (SQLException e) {
			e.printStackTrace();
			 try {
				 if(cn != null)cn.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}
		return ids;
	}
	
	@Transactional
	public int importFolder(int toid,File wr,User u){
		Section s = emp.get().find(Section.class, toid);
		File af = new File(wr,"migrationfolder");
		File[] files = af.listFiles();
		ErrorMessages ems = injector.getInstance(ErrorMessages.class);
		int count = 0;
		for(File f : files){
			String ac = fps.getContents(f, "utf-8");
			JSONObject jo = JSONObject.fromObject(ac);
			Article a = new Article();
			a.setTitle(jo.getString("title"));
			a.setContent(jo.getString("content"));
			if(jo.containsKey("excerpt"))a.setExcerpt(jo.getString("excerpt"));
			if(jo.containsKey("createdAt"))a.setCreatedAt(new Date(jo.getLong("createdAt")));
			if(jo.containsKey("createdAt"))a.setPublishedAt(new Date(jo.getLong("publishedAt")));
			if(jo.containsKey("updatedAt"))a.setUpdatedAt(new Date(jo.getLong("updatedAt")));
			a.setDefaultSectionId(s.getId());
			s.manageRelation(a, true, "", ems);
			a.setSiteId(s.getSiteId());
			a.setCreator(u);
			emp.get().persist(a);
			f.delete();
			count++;
			if(count > 20)break;
		}
		emp.get().merge(s);
		return count;
	}
	
    public int exportFolder(String fid,File wr) {
		JsonConfig jc = new JsonConfig();
//		jc.registerJsonValueProcessor(Date.class, injector.getInstance(JsonlibDateValueProssor.class));

        Connection cn = null;
        int count = 0;
        try {
            cn = tcmsds.getConnection();
            String query = "select * from contents where sectionids like '%" + fid + "%'";
            Statement st = cn.createStatement();
            ResultSet rs = st.executeQuery(query);
            File sf = new File(wr, "migrationfolder");
            if(!sf.exists())sf.mkdir();
            while (rs.next())
            {
            	count++;
	        	JSONObject jo = new JSONObject();
	        	jo.element("title", rs.getString("title"));
	        	jo.element("content", rs.getString("body"));
	        	jo.element("excerpt", rs.getString("excerpt"));
	        	jo.element("publishedAt", rs.getDate("publishedAt").getTime());
	        	jo.element("createdAt", rs.getDate("createdAt").getTime());
	        	jo.element("updatedAt", rs.getDate("updatedAt").getTime());
	        	File af = new File(sf,rs.getString("id"));
	        	try {
					fps.setContents(af, jo.toString(), "utf-8");
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
            }
            // Use the connection
        } catch (SQLException e) {
			e.printStackTrace();
		} finally {
            try {
                cn.close();
            } catch (Exception e) {}
        }
		return count;
    }
}
/*
 * mysql> select * from contents where sectionids like '%EA5EDF50D5D511DE8714F1C73CBE188A%';
 * 
 * 
public class Article extends Content implements Serializable{
	private static final long serialVersionUID = -357283919307181886L;
	
	
	@ManyToMany(fetch = FetchType.LAZY,cascade=CascadeType.MERGE)
	@OrderBy("id DESC")
	@JoinTable(name = "Article_Section")
	private List<Section> sections = new ArrayList<Section>();
	
	
	@ManyToMany(fetch = FetchType.LAZY)
	@OrderBy("createdAt DESC")
	@JoinTable(name = "article_myasset")
	private List<MyAsset> myAssets = new ArrayList<MyAsset>();
	
	
	public MyAsset getTupian(){
		if(myAssets == null)return null;
		for (MyAsset ma : myAssets) {
			if(ma.isImg())return ma;
		}
		return null;
	}
	

	@Lob
	private String section2ids;
	
	@Lob
	private String sectionids;
	
	@Lob
	private String attached_assets_ids;
	
	private String atype;

	
	public void addMyasset(MyAsset myasset) {
		if (!this.myAssets.contains(myasset)) {
			this.myAssets.add(myasset);
		}
	}

	public void addSection(Section section) {
		if (!this.sections.contains(section)) {
			this.sections.add(section);
		}
	}
	


	public String createdAtSimple() {
		Format sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(getCreatedAt());
	}
	

	public String getAttached_assets_ids() {
		return attached_assets_ids;
	}




	public MyAsset getFirstImg(){
		for (MyAsset a : myAssets) {
			if(a.isImg())return a;
		}
		return null;
	}

	public List<MyAsset> getMyAssets() {
		return myAssets;
	}
	
	public String getSection2ids() {
		return section2ids;
	}
	

	public String getSectionids() {
		return sectionids;
	}
	
	public List<Section> getSections() {
		return sections;
	}

	public void setAttached_assets_ids(String attached_assets_ids) {
		this.attached_assets_ids = attached_assets_ids;
	}

	public void setMyAssets(List<MyAsset> myAssets) {
		this.myAssets = myAssets;
	}

	public void setSection2ids(String section2ids) {
		this.section2ids = section2ids;
	}

	public void setSectionids(String sectionids) {
		this.sectionids = sectionids;
	}


	public void setSections(List<Section> sections) {
		this.sections = sections;
	}

	public void setAtype(String atype) {
		this.atype = atype;
	}

	public String getAtype() {
		return atype;
	}
}

public abstract class Content implements Serializable{
	private static final long serialVersionUID = 6358995349912260725L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO,generator="uuid-hex")
	protected String id;
	
	private String state;
	
	private int counter;
	
	private String tpl;
	
	@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.REMOVE)
	private List<GeneralComment> comments;
	
	
	@OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.MERGE)
	@JoinColumn(name="older_id")
	private Content older;
	
	@OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.MERGE)
	@JoinColumn(name="earlier_id")
	private Content earlier;
	
	protected String dsp_page_name; 

	protected String title;
	protected String titleTwo;

	protected String titleThree;

	protected String permalink;
	
	private String src;
	
	@Enumerated(EnumType.STRING)
	private YongChu yongchu;

	@Lob
	protected String excerpt;

	@Lob
	protected String body;

	@Lob
	protected String bodyTwo;

	@Lob
	protected String bodyThree;

	@Temporal(TemporalType.TIMESTAMP)
	protected Date createdAt;

	@Temporal(TemporalType.TIMESTAMP)
	protected Date updatedAt;
	@Temporal(TemporalType.TIMESTAMP)
	protected Date publishedAt;
	
	@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.MERGE)
	@JoinColumn(name="author_id")
	protected User author;
	
	
	@ManyToMany(fetch=FetchType.LAZY,cascade=CascadeType.PERSIST)
	@JoinTable(name = "taggings")
	private Set<Tag> tags = new HashSet<Tag>();


	protected String authorEmail;
	protected String authorIp;

	@ManyToOne
	@JoinColumn(name="updater_id")
	protected User updater;
	
	


	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "site_id")
	protected Site site;
	
	protected Boolean approved;
	@Version
	protected Integer version;
	protected String readableId;
	
	
	@OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.MERGE)
	@JoinColumn(name="main_section_base_id")
	private SectionBase mainSectionBase;
	
	
	private String mainSectionReadableId;
	
	private String mainSectionName;
	
	
	

	public Boolean getApproved() {
		return approved;
	}

	public String getAuthorEmail() {
		return authorEmail;
	}
	public String getAuthorIp() {
		return authorIp;
	}

	public String getBody() {
		return body;
	}

	public String getBodyThree() {
		return bodyThree;
	}
	public String getBodyTwo() {
		return bodyTwo;
	}
	
	public int getCounter() {
		return counter;
	}





	public Date getCreatedAt() {
		return createdAt;
	}

	public String getExcerpt() {
		return excerpt;
	}

	public String getId() {
		return id;
	}

	public SectionBase getMainSectionBase() {
		return mainSectionBase;
	}

	
	public String getPermalink() {
		return permalink;
	}

	
	
	public Date getPublishedAt() {
		return publishedAt;
	}


	public String getReadableId() {
		return readableId;
	}


	public Site getSite() {
		return site;
	}

	public String getState() {
		return state;
	}


	// required, max, min, maxLength, minLength and regexp,comma separated list;
	public String getTitle() {
		return title;
	}

	public String getTitleThree() {
		return titleThree;
	}


	public String getTitleTwo() {
		return titleTwo;
	}

	public Date getUpdatedAt() {
		return updatedAt;
	}



	
	public Integer getVersion() {
		return version;
	}


	public void setApproved(Boolean approved) {
		this.approved = approved;
	}

	public void setAuthorEmail(String authorEmail) {
		this.authorEmail = authorEmail;
	}

	public void setAuthorIp(String authorIp) {
		this.authorIp = authorIp;
	}


	public void setBody(String body) {
		this.body = body;
	}

	public void setBodyThree(String bodyThree) {
		this.bodyThree = bodyThree;
	}

	public void setBodyTwo(String bodyTwo) {
		this.bodyTwo = bodyTwo;
	}
	
	public void setCounter(int counter) {
		this.counter = counter;
	}

	public void setCreatedAt(Date createdAt) {
		this.createdAt = createdAt;
	}



	public void setExcerpt(String excerpt) {
		this.excerpt = excerpt;
	}


	public void setId(String id) {
		this.id = id;
	}

	public void setMainSectionBase(SectionBase mainSectionBase) {
		this.mainSectionBase = mainSectionBase;
	}


	public void setPermalink(String permalink) {
		this.permalink = permalink;
	}

	public void setPublishedAt(Date publishedAt) {
		this.publishedAt = publishedAt;
	}

	public void setReadableId(String readableId) {
		this.readableId = readableId;
	}
	
	public void setSite(Site site) {
		this.site = site;
	}

	public void setState(String state) {
		this.state = state;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public void setTitleThree(String titleThree) {
		this.titleThree = titleThree;
	}

	public void setTitleTwo(String titleTwo) {
		this.titleTwo = titleTwo;
	}

	public void setUpdatedAt(Date updatedAt) {
		this.updatedAt = updatedAt;
	}


	public void setVersion(Integer version) {
		this.version = version;
	}
	
	
	public void setSrc(String src) {
		this.src = src;
	}
	public String getSrc() {
		return src;
	}
	public String getDsp_page_name() {
		return dsp_page_name;
	}
	public void setDsp_page_name(String dsp_page_name) {
		this.dsp_page_name = dsp_page_name;
	}
	public User getAuthor() {
		return author;
	}
	public void setAuthor(User author) {
		this.author = author;
	}
	
	public User getUpdater() {
		return updater;
	}
	public void setUpdater(User updater) {
		this.updater = updater;
	}

	public void setOlder(Content older) {
		this.older = older;
	}

	public Content getOlder() {
		return older;
	}

	public void setEarlier(Content earlier) {
		this.earlier = earlier;
	}

	public Content getEarlier() {
		return earlier;
	}


	public void setTags(Set<Tag> tags) {
		this.tags = tags;
	}

	public Set<Tag> getTags() {
		return tags;
	}

	public void setYongchu(YongChu yongchu) {
		this.yongchu = yongchu;
	}

	public YongChu getYongchu() {
		return yongchu;
	}
	
	
	
	public String getPublishedAt(String dateFormat){
		if(publishedAt == null)return "";
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(publishedAt);
	}
	
	public String getCreatedAt(String dateFormat){
		if(createdAt == null)return "";
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(createdAt);
	}

	public String getUpdatedAt(String dateFormat){
		if(updatedAt == null)return "";
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(updatedAt);
	}
	
	

	
	public String getTitle(int length){
		if(length < 1)length =0;
		if(title == null)return "";
		if(title.length()<length){
			return title;
		}else{
			return title.substring(0, length-1)+"...";
		}
	}
	
	public String getExcerpt(int length){
		if(length < 1)length =0;
		if(excerpt == null)return "";
		if(excerpt.length()<length){
			return excerpt;
		}else{
			return excerpt.substring(0, length-1)+"...";
		}
	}

	
	public String getBody(int length){
		if(length < 1)length =0;
		if(body.length()<length){
			return body;
		}else{
			return body.substring(0, length-1);
		}
	}
	
	public String getBodyNoHtml(int length){
		String s = body.replaceAll("<([^>]+)>", "");
		if(length < 1)length =0;
		if(s.length()<length){
			return s;
		}else{
			return s.substring(0, length-1);
		}
	}

	public void setMainSectionReadableId(String mainSectionReadableId) {
		this.mainSectionReadableId = mainSectionReadableId;
	}

	public String getMainSectionReadableId() {
		return mainSectionReadableId;
	}

	public void setMainSectionName(String mainSectionName) {
		this.mainSectionName = mainSectionName;
	}

	public String getMainSectionName() {
		return mainSectionName;
	}

	public void setComments(List<GeneralComment> comments) {
		this.comments = comments;
	}

	public List<GeneralComment> getComments() {
		return comments;
	}

	public void setTpl(String tpl) {
		this.tpl = tpl;
	}

	public String getTpl() {
		return tpl;
	}
	
}


public abstract class SectionBase implements Serializable{

	private static final long serialVersionUID = 4660296376629130651L;
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO,generator="uuid-hex")
	@Column(nullable = false)
	private String id;
	
	@Version
	private Integer version;
	private String readableId;
	private String myReadableId;
	private String name;
	

	private boolean linkitem;
	
	private String tpl;
	private String ctpl;
	
	
	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(name="sb_allowquns")
	private List<Qun> allowQuns = new ArrayList<Qun>();
	
	private boolean protectme;
	
	
	@ManyToOne(fetch=FetchType.EAGER)
	@JoinColumn(name="linktoId",referencedColumnName="id")
	private SectionBase linkto;
	
	@OneToMany(mappedBy="linkto",fetch=FetchType.LAZY)
	private List<Base> linkfroms;
	
	private String tubiao_url;
	private String target_url;
	
	private int priority;
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "owner_id")
	private User owner;
	
	@Lob
	private String assets_map;
	
	@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.MERGE)
	@JoinColumn(name = "site_id")
	private Site site;
	
	
	private Integer myposition;
	
	@ManyToOne(fetch=FetchType.LAZY,cascade={CascadeType.MERGE,CascadeType.PERSIST})
	@JoinColumn(name="parentId",referencedColumnName="id")
	private SectionBase parent;

	
	@OneToOne(fetch=FetchType.LAZY,cascade={CascadeType.MERGE,CascadeType.PERSIST})
	@JoinColumn(name="assetSectionId",referencedColumnName="id")
	private SectionBase assetSection;

	
	@Temporal(TemporalType.TIMESTAMP)
	private Date created_at;
	
	@OneToMany(mappedBy="parent",fetch=FetchType.LAZY)
	@OrderBy(value="myposition ASC")
	private List<SectionBase> children = new ArrayList<SectionBase>();
	
	private boolean special;
	private boolean nodelete;
	
	private String defaultView;
	
	@Lob
	private String description;
	
	

	public  List<SectionBase> getChildren() {
		return children;
	}
	
	
	
	public Date getCreated_at() {
		if(created_at == null)return new Date();
		return created_at;
		
		
	}
	


	@NonVisual
	public String getId() {
		return id;
	}


	public Integer getMyposition() {
		return myposition;
	}
	
	public String getName() {
		return name;
	}
	

	public SectionBase getParent() {
		return  parent;
	}

	public String getReadableId() {
		return readableId;
	}
	
	
	public Site getSite() {
		return site;
	}
	
	public String getTarget_url() {
		return target_url;
	}
	
	public String getTubiao_url() {
		return tubiao_url;
	} 
	
	public Integer getVersion() {
		return version;
	}

	public boolean isSpecial() {
		return special;
	}

	public void setChildren(List<SectionBase> children) {
		this.children = children;
	}


	public void setCreated_at(Date created_at) {
		this.created_at = created_at;
	}


	public void setId(String id) {
		this.id = id;
	}

	
	public void setMyposition(Integer position) {
		this.myposition = position;
	}


	public void setName(String name) {
		this.name = name;
	}


	public void setParent(SectionBase parent) {
		this.parent = parent;
	}


	public void setReadableId(String readableId) {
		this.readableId = readableId;
	}


	public void setSite(Site site) {
		this.site = site;
	}


	public void setSpecial(boolean special) {
		this.special = special;
	}


	public void setTarget_url(String target_url) {
		this.target_url = target_url;
	}
	
	public void setTubiao_url(String tubiao_url) {
		this.tubiao_url = tubiao_url;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}


	public void setAssets_map(String assets_map) {
		this.assets_map = assets_map;
	}


	public String getAssets_map() {
		return assets_map;
	}


	public void setPriority(int priority) {
		this.priority = priority;
	}


	public int getPriority() {
		return priority;
	}


	public void setDefaultView(String defaultView) {
		this.defaultView = defaultView;
	}


	public String getDefaultView() {
		return defaultView;
	}


	public void setDescription(String description) {
		this.description = description;
	}


	public String getDescription() {
		return description;
	}


	public void setNodelete(boolean nodelete) {
		this.nodelete = nodelete;
	}


	public boolean isNodelete() {
		return nodelete;
	}


	public void setAssetSection(SectionBase assetSection) {
		this.assetSection = assetSection;
	}


	public SectionBase getAssetSection() {
		return assetSection;
	}


	public void setOwner(User owner) {
		this.owner = owner;
	}


	public User getOwner() {
		return owner;
	}


	public void setMyReadableId(String myReadableId) {
		this.myReadableId = myReadableId;
	}


	public String getMyReadableId() {
		return myReadableId;
	}


	public void setLinkto(SectionBase linkto) {
		this.linkto = linkto;
	}


	public SectionBase getLinkto() {
		return linkto;
	}


	public void setTpl(String tpl) {
		this.tpl = tpl;
	}


	public String getTpl() {
		return tpl;
	}


	public void setLinkfroms(List<SectionBase> linkfroms) {
		this.linkfroms = linkfroms;
	}


	public List<SectionBase> getLinkfroms() {
		return linkfroms;
	}


	public void setLinkitem(boolean linkitem) {
		this.linkitem = linkitem;
	}


	public boolean isLinkitem() {
		return linkitem;
	}



	public void setAllowQuns(List<Qun> allowQuns) {
		this.allowQuns = allowQuns;
	}



	public List<Qun> getAllowQuns() {
		return allowQuns;
	}



	public void setProtectme(boolean protectme) {
		this.protectme = protectme;
	}



	public boolean isProtectme() {
		return protectme;
	}



	public void setCtpl(String ctpl) {
		this.ctpl = ctpl;
	}



	public String getCtpl() {
		return ctpl;
	}
	
	@Entity
public class Section extends SectionBase implements Serializable {

	private static final long serialVersionUID = -8890595657659689535L;

	
	

	@ManyToMany(mappedBy = "sections")
	@OrderBy("publishedAt DESC")
	private List<Article> articles = new ArrayList<Article>();
	
	public void addArticle(Article article) {
		if (!this.articles.contains(article)) {
			this.articles.add(article);
		}
	}

	public List<Article> getArticles() {
		return articles;
	}


	public void removeArticle(Article article) {
		this.articles.remove(article);
	}

	public void setArticles(List<Article> articles) {
		this.articles = articles;
	}




}

 */
